home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Common.c
-
- Contains: HackTV cross-platform common code
-
- Written by: Gary Woodcock
- Updated by: Brian Friedkin
-
- Copyright: © 1992-1998 by Apple Computer, Inc.
- */
- #include <QTML.h>
- #include <Endian.h>
- #include <Menus.h>
- #include <Printing.h>
- #include <Script.h>
- #include <Scrap.h>
- #include <QuickTimeComponents.h>
- #include <ImageCodec.h>
- #include <ColorPicker.h>
- #include "Globals.h"
- #include "Common.h"
-
- GWorldPtr gTempFrame = NULL;
- QTAtomContainer gEffectDesc = nil;
- ImageSequence gEffectSequenceID = 0;
- ImageDescriptionHandle gSampleDescription = NULL;
- TimeBase gTimeBase = NULL;
- unsigned long gNumFrames = 0;
- unsigned long gSeconds = 0;
- unsigned long gStartSeconds = 0;
- RGBColor gColorToReplace = { 0, 0, 0 };
- RGBColor gColorToReplaceWith = { 0, 65535, 0 };
- Boolean gParental = false;
-
- // Disable warnings associated with "\p" strings
- #if TARGET_OS_WIN32
- #pragma warning(disable: 4129)
- #endif
-
- static OSErr XorRectToRgn(Rect *srcRectA, Rect *srcRectB, RgnHandle *destRgn);
-
- /* ---------------------------------------------------------------------- */
-
- void InitializeSequenceGrabber(void)
- {
- ComponentDescription theDesc;
- ComponentResult result = noErr;
- GrafPtr savedPort;
- Component sgCompID;
-
- gQuitFlag = false;
- gSeqGrabber = 0L;
- gVideoChannel = 0L;
- gSoundChannel = 0L;
- gMonitorPICT = nil;
- gPrintRec = (THPrint) NewHandleClear (sizeof (TPrint));
-
- // Find and open a sequence grabber
- theDesc.componentType = SeqGrabComponentType;
- theDesc.componentSubType = 0L;
- theDesc.componentManufacturer = 'appl';
- theDesc.componentFlags = 0L;
- theDesc.componentFlagsMask = 0L;
- sgCompID = FindNextComponent (nil, &theDesc);
- if (sgCompID != 0L)
- gSeqGrabber = OpenComponent (sgCompID);
-
- // If we got a sequence grabber, set it up
- if (gSeqGrabber != 0L)
- {
- // Get the monitor
- CreateMonitorWindow();
- if (gMonitor != nil)
- {
- // Display the monitor window
- GetPort (&savedPort);
- MacSetPort (gMonitor);
- MacMoveWindow(gMonitor, 10, 30 + GetMBarHeight(), 0);
- MacShowWindow (gMonitor);
-
- // Initialize the sequence grabber
- result = SGInitialize (gSeqGrabber);
- if (result == noErr)
- {
- gTempFrame = MakeOffscreenGWorld ();
- gTimeBase = NewTimeBase ();
- LinkUpSources ();
- result = SGSetGWorld (gSeqGrabber, gTempFrame, nil);
-
- // Get a video channel
- result = SGNewChannel (gSeqGrabber, VideoMediaType, &gVideoChannel);
- if ((gVideoChannel != nil) && (result == noErr))
- {
- short width;
- short height;
-
- gQuarterSize = false;
- gHalfSize = true;
- gFullSize = false;
-
- result = SGGetSrcVideoBounds (gVideoChannel, &gActiveVideoRect);
- width = (gActiveVideoRect.right - gActiveVideoRect.left)/*/ 2*/;
- height = (gActiveVideoRect.bottom - gActiveVideoRect.top)/* / 2*/;
- SizeWindow (gMonitor, width, height, false);
-
- result = SGSetChannelUsage (gVideoChannel, seqGrabPreview | seqGrabRecord | seqGrabPlayDuringRecord);
- result = SGSetChannelBounds (gVideoChannel, &(gMonitor->portRect));
- }
-
- // Get a sound channel
- result = SGNewChannel (gSeqGrabber, SoundMediaType, &gSoundChannel);
-
- if ((gSoundChannel != nil) && (result == noErr))
- {
- if (gSoundChannel != nil)
- {
- result = SGSetChannelUsage (gSoundChannel, seqGrabPreview | seqGrabRecord);
-
- // Set the volume low to prevent feedback when we start the preview,
- // in case the mic is anywhere near the speaker.
- result = SGSetChannelVolume (gSoundChannel, 0x0010);
- }
- }
-
- // Get the alignment proc (for use when dragging the monitor)
- result = SGGetAlignmentProc (gSeqGrabber, &gSeqGrabberAlignProc);
- }
-
- // Go!
- if (result == noErr)
- result = SGStartPreview (gSeqGrabber);
- MacSetPort (savedPort);
- }
- }
- }
-
- /* ---------------------------------------------------------------------- */
-
- // Specify and setup a file to contain this track's data
- static ComponentResult SetTrackFile(SGChannel theChannel, StringPtr prompt, StringPtr defaultName)
- {
- StandardFileReply reply;
- ComponentResult err;
- SGOutput theOutput;
- AliasHandle alias = 0;
-
- // Get the destination filename
- StandardPutFile(prompt, defaultName, &reply);
- if (!reply.sfGood)
- {
- err = fnfErr;
- goto bail;
- }
-
- // Make an alias from the filename
- if (err = QTNewAlias(&reply.sfFile, &alias, true)) goto bail;
-
- // Create an output from this file
- if (err = SGNewOutput(gSeqGrabber, (Handle)alias, rAliasType, seqGrabToDisk, &theOutput)) goto bail;
-
- // Associate this output with the specified channel
- if (err = SGSetChannelOutput(gSeqGrabber, theChannel, theOutput)) goto bail;
-
- bail:
- if (alias) DisposeHandle((Handle)alias);
- return err;
- }
-
- /* ---------------------------------------------------------------------- */
-
- // Record a movie
- void DoRecord(void)
- {
- long err;
- StandardFileReply reply;
-
- // Stop everything while the dialogs are up
- SGStop(gSeqGrabber);
-
- // Get the destination filename
- StandardPutFile("\pSave new movie file as:", "\pHack.mov", &reply);
- if (!reply.sfGood)
- {
- err = fnfErr;
- goto bail;
- }
- if ((err = SGSetDataOutput(gSeqGrabber, &reply.sfFile, seqGrabToDisk)))
- goto bail;
-
- // Ask use for separate video and sound track files if requested
- if (gSoundChannel && gRecordSound && gVideoChannel && gRecordVideo && gSplitTracks)
- {
- if ((err = SetTrackFile(gVideoChannel, "\pSave video track file as:", "\pHackVideo.trk")))
- goto bail;
- if ((err = SetTrackFile(gSoundChannel, "\pSave sound track file as:", "\pHackSound.trk")))
- goto bail;
- }
-
- // If not recording sound or video, then "disable" those channels
- if (gSoundChannel && !gRecordSound)
- SGSetChannelUsage(gSoundChannel, 0);
- if (gVideoChannel && !gRecordVideo)
- SGSetChannelUsage(gVideoChannel, 0);
-
- // Attempt to recover the preview area obscured by dialogs
- #if TARGET_OS_WIN32
- UpdatePort(gMonitor);
- #endif
- SGUpdate(gSeqGrabber, 0);
-
- // Make the movie file
- DeleteMovieFile(&reply.sfFile);
- if (err = CreateMovieFile(&reply.sfFile, 'TVOD', smSystemScript,
- createMovieFileDontOpenFile | createMovieFileDontCreateMovie | createMovieFileDontCreateResFile,
- nil, nil)) goto bail;
-
- FlushEvents(mDownMask+mUpMask,0);
-
- // Record!
- if (err = SGStartRecord(gSeqGrabber))
- goto bail;
-
- while (!Button() && (err == noErr))
- {
- err = SGIdle(gSeqGrabber);
- }
-
- // If we recorded until we ran out of space, then allow SGStop to be
- // called to write the movie resource. The assumption here is that the
- // data output filled up but the disk has enough free space left to
- // write the movie resource.
- if (!((err == dskFulErr) || (err != eofErr)))
- goto bail;
- err = SGStop(gSeqGrabber);
- NoteAlert(kMovieHasBeenRecordedAlertID, 0);
- err = SGStartPreview(gSeqGrabber);
-
- return;
-
- bail:
- SGPause(gSeqGrabber, false);
- SGStartPreview(gSeqGrabber);
- }
-
- /* ---------------------------------------------------------------------- */
-
- void DoAboutDialog(void)
- {
- short itemHit;
- DialogPtr aboutDialog;
-
- aboutDialog = GetNewDialog(kAboutDLOGID, nil, (WindowPtr)-1L);
-
- // Do the boring about dialog
- SetDialogDefaultItem(aboutDialog, 1);
- MacShowWindow(aboutDialog);
- do
- {
- ModalDialog(nil, &itemHit);
- }
- while (itemHit != 1);
- DisposeDialog(aboutDialog);
- }
-
- /* ---------------------------------------------------------------------- */
-
- void DoPageSetup(void)
- {
- PrOpen();
- PrStlDialog(gPrintRec);
- PrClose();
- }
-
- /* ---------------------------------------------------------------------- */
-
- void DoPrint(void)
- {
- TPPrPort printPort;
- TPrStatus printStatus;
- ComponentResult err;
- Rect tempRect;
-
- // Copy a frame from the monitor
- if (gMonitorPICT != nil)
- KillPicture (gMonitorPICT);
- gMonitorPICT = nil;
- err = SGGrabPict(gSeqGrabber, &gMonitorPICT, nil, 0, grabPictOffScreen);
- if ((err == noErr) && (gMonitorPICT != nil))
- {
- // Print it
- HLock((Handle) gMonitorPICT);
- PrOpen();
- if (PrJobDialog (gPrintRec))
- {
- printPort = PrOpenDoc (gPrintRec, nil, nil);
- err = PrError();
- PrOpenPage (printPort, 0);
- err = PrError();
-
- tempRect = (**gMonitorPICT).picFrame;
- tempRect.left = EndianS16_BtoN(tempRect.left);
- tempRect.top = EndianS16_BtoN(tempRect.top);
- tempRect.right = EndianS16_BtoN(tempRect.right);
- tempRect.bottom = EndianS16_BtoN(tempRect.bottom);
- DrawPicture(gMonitorPICT, &tempRect);
-
- PrClosePage (printPort);
- err = PrError();
- PrCloseDoc (printPort);
- err = PrError();
- if ((**gPrintRec).prJob.bJDocLoop == bSpoolLoop)
- {
- PrPicFile (gPrintRec, 0, 0, 0, &printStatus);
- err = PrError();
- }
- }
- PrClose();
- err = PrError();
- HUnlock((Handle) gMonitorPICT);
- }
- }
-
- /* ---------------------------------------------------------------------- */
-
- void DoCopyToClipboard(void)
- {
- ComponentResult err;
-
- // Copy a frame from the monitor
- if (gMonitorPICT != nil)
- KillPicture (gMonitorPICT);
- gMonitorPICT = nil;
- err = SGGrabPict (gSeqGrabber, &gMonitorPICT, nil, 0, grabPictOffScreen);
- if ((err == noErr) && (gMonitorPICT != nil))
- {
- err = ZeroScrap();
- HLock ((Handle) gMonitorPICT);
- err = PutScrap (GetHandleSize ((Handle) gMonitorPICT), 'PICT', *(Handle)gMonitorPICT);
- HUnlock ((Handle) gMonitorPICT);
- }
- }
-
- /* ---------------------------------------------------------------------- */
-
- static pascal Boolean
- SeqGrabberModalFilterProc (DialogPtr theDialog, EventRecord *theEvent,
- short *itemHit, long refCon)
- {
- // Ordinarily, if we had multiple windows we cared about, we'd handle
- // updating them in here, but since we don't, we'll just clear out
- // any update events meant for us
-
- Boolean handled = false;
-
- if ((theEvent->what == updateEvt) &&
- ((WindowPtr) theEvent->message == (WindowPtr) refCon))
- {
- WindowPtr wPtr = (WindowPtr) refCon;
- BeginUpdate (wPtr);
- EndUpdate (wPtr);
- handled = true;
- }
-
- return (handled);
- }
-
- /* ---------------------------------------------------------------------- */
-
- void DoVideoSettings(void)
- {
- Rect newActiveVideoRect;
- Rect adjustedActiveVideoRect;
- Rect curBounds, curVideoRect, newVideoRect, newBounds;
- short width, height;
- ComponentResult err;
- GrafPtr savedPort;
- RgnHandle deadRgn;
- SGModalFilterUPP seqGragModalFilterUPP;
-
- // Get our current state
- err = SGGetChannelBounds (gVideoChannel, &curBounds);
- err = SGGetVideoRect (gVideoChannel, &curVideoRect);
-
- // Pause
- err = SGPause (gSeqGrabber, true);
-
- // Do the dialog thang
- seqGragModalFilterUPP = (SGModalFilterUPP)NewSGModalFilterProc(SeqGrabberModalFilterProc);
- err = SGSettingsDialog(gSeqGrabber, gVideoChannel, 0,
- nil, 0L, seqGragModalFilterUPP, (long)StripAddress ((Ptr) gMonitor));
- DisposeRoutineDescriptor(seqGragModalFilterUPP);
-
- // What happened?
- err = SGGetVideoRect (gVideoChannel, &newVideoRect);
- err = SGGetSrcVideoBounds (gVideoChannel, &newActiveVideoRect);
-
- // Set up our port
- GetPort (&savedPort);
- MacSetPort (gMonitor);
-
- // Has our active rect changed?
- // If so, it's because our video standard changed (e.g., NTSC to PAL),
- // and we need to adjust our monitor window
- if (!MacEqualRect (&gActiveVideoRect, &newActiveVideoRect))
- {
- if (gFullSize)
- {
- width = newActiveVideoRect.right - newActiveVideoRect.left;
- height = newActiveVideoRect.bottom - newActiveVideoRect.top;
-
- gActiveVideoRect = newActiveVideoRect;
- SizeWindow (gMonitor, width, height, false);
- err = SGSetChannelBounds (gVideoChannel, &(gMonitor->portRect));
- }
- else if (gHalfSize)
- {
- width = (newActiveVideoRect.right - newActiveVideoRect.left) / 2;
- height = (newActiveVideoRect.bottom - newActiveVideoRect.top) / 2;
-
- gActiveVideoRect = newActiveVideoRect;
- SizeWindow (gMonitor, width, height, false);
- err = SGSetChannelBounds (gVideoChannel, &(gMonitor->portRect));
- }
- else if (gQuarterSize)
- {
- width = (newActiveVideoRect.right - newActiveVideoRect.left) / 4;
- height = (newActiveVideoRect.bottom - newActiveVideoRect.top) / 4;
-
- gActiveVideoRect = newActiveVideoRect;
- SizeWindow (gMonitor, width, height, false);
- err = SGSetChannelBounds (gVideoChannel, &(gMonitor->portRect));
- }
- }
-
- // Has our crop changed?
- // This code shows how to be crop video panel friendly
- // Two important things -
- // 1) Be aware that you might have been cropped and adjust your
- // video window appropriately
- // 2) Be aware that you might have been adjusted and attempt to
- // account for this. Adjusting refers to using the digitizer
- // rect to "adjust" the active source rect within the maximum
- // source rect. This is useful if you're getting those nasty
- // black bands on the sides of your video display - you can use
- // the control-arrow key sequence to shift the active source
- // rect around when you're in the crop video panel
-
- adjustedActiveVideoRect = gActiveVideoRect;
- if (!MacEqualRect (&curVideoRect, &newVideoRect))
- {
- if ((newVideoRect.left < gActiveVideoRect.left) ||
- (newVideoRect.right > gActiveVideoRect.right) ||
- (newVideoRect.top < gActiveVideoRect.top) ||
- (newVideoRect.bottom > gActiveVideoRect.bottom))
- {
- if (newVideoRect.left < gActiveVideoRect.left)
- {
- adjustedActiveVideoRect.left = newVideoRect.left;
- adjustedActiveVideoRect.right -= (gActiveVideoRect.left - newVideoRect.left);
- }
- if (newVideoRect.right > gActiveVideoRect.right)
- {
- adjustedActiveVideoRect.right = newVideoRect.right;
- adjustedActiveVideoRect.left += (newVideoRect.right - gActiveVideoRect.right);
- }
- if (newVideoRect.top < gActiveVideoRect.top)
- {
- adjustedActiveVideoRect.top = newVideoRect.top;
- adjustedActiveVideoRect.bottom -= (gActiveVideoRect.top - newVideoRect.top);
- }
- if (newVideoRect.bottom > gActiveVideoRect.bottom)
- {
- adjustedActiveVideoRect.bottom = newVideoRect.bottom;
- adjustedActiveVideoRect.top += (newVideoRect.bottom - gActiveVideoRect.bottom);
- }
- newBounds = newVideoRect;
- MapRect (&newBounds, &adjustedActiveVideoRect, &(gMonitor->portRect));
- }
- else // Can't tell if we've been adjusted (digitizer rect is smaller on all sides
- // than the active source rect)
- {
- newBounds = newVideoRect;
- MapRect (&newBounds, &gActiveVideoRect, &(gMonitor->portRect));
- }
- width = newBounds.right - newBounds.left;
- height = newBounds.bottom - newBounds.top;
- err = SGSetChannelBounds (gVideoChannel, &newBounds);
- }
-
- // Clean out the part of the port that isn't being drawn in
- deadRgn = NewRgn();
- if (deadRgn != nil)
- {
- Rect boundsRect;
- err = SGGetChannelBounds (gVideoChannel, &boundsRect);
- err = XorRectToRgn (&boundsRect, &(gMonitor->portRect), &deadRgn);
- EraseRgn (deadRgn);
- DisposeRgn (deadRgn);
- }
-
- MacSetPort (savedPort);
-
- #if !TARGET_OS_MAC
- // This is necessary, for now, to get the grab to start again afer the
- // dialog goes away. For some reason the video destRect never gets reset to point
- // back to the monitor window.
- SGSetChannelBounds (gVideoChannel, &(gMonitor->portRect));
- #endif
-
- // The pause that refreshes
- err = SGPause (gSeqGrabber, false);
- }
-
- /* ---------------------------------------------------------------------- */
-
- void DoSoundSettings(void)
- {
- SGModalFilterUPP seqGragModalFilterUPP;
- ComponentResult err;
-
- seqGragModalFilterUPP = (SGModalFilterUPP)NewSGModalFilterProc(SeqGrabberModalFilterProc);
- err = SGSettingsDialog (gSeqGrabber, gSoundChannel, 0,
- nil, 0L, seqGragModalFilterUPP, (long) StripAddress ((Ptr) gMonitor));
- DisposeRoutineDescriptor(seqGragModalFilterUPP);
- }
-
- /* ---------------------------------------------------------------------- */
-
- void DoResize(short divisor)
- {
- short width, height;
- GrafPtr savedPort;
- Rect curBounds, maxBoundsRect;
- RgnHandle deadRgn;
- ComponentResult err;
-
- // New width and height
- width = (gActiveVideoRect.right - gActiveVideoRect.left) / divisor;
- height = (gActiveVideoRect.bottom - gActiveVideoRect.top) / divisor;
-
- gQuarterSize = (divisor == 4 ? true : false);
- gHalfSize = (divisor == 2 ? true : false);
- gFullSize = (divisor == 1 ? true : false);
-
- // Resize the monitor
- GetPort (&savedPort);
- MacSetPort (gMonitor);
- err = SGPause (gSeqGrabber, true);
- err = SGGetChannelBounds (gVideoChannel, &curBounds);
- maxBoundsRect = gMonitor->portRect;
- SizeWindow (gMonitor, width, height, false);
- MapRect (&curBounds, &maxBoundsRect, &(gMonitor->portRect));
- err = SGSetChannelBounds (gVideoChannel, &curBounds);
-
- // Clean out part of port we're not drawing in
- deadRgn = NewRgn();
- if (deadRgn != nil)
- {
- Rect boundsRect;
-
- err = SGGetChannelBounds (gVideoChannel, &boundsRect);
- err = XorRectToRgn (&boundsRect, &(gMonitor->portRect), &deadRgn);
- EraseRgn (deadRgn);
- DisposeRgn (deadRgn);
- }
-
- MacSetPort (savedPort);
- err = SGPause (gSeqGrabber, false);
- }
-
- /* ---------------------------------------------------------------------- */
-
- static OSErr XorRectToRgn (Rect *srcRectA, Rect *srcRectB, RgnHandle *destRgn)
- {
- RgnHandle srcRgnA = NewRgn();
- RgnHandle srcRgnB = NewRgn();
- OSErr result = noErr;
-
- if ((destRgn != nil) && (*destRgn != nil))
- {
- if ((srcRgnA != nil) &&
- (srcRgnB != nil))
- {
- RectRgn (srcRgnA, srcRectA);
- RectRgn (srcRgnB, srcRectB);
- MacXorRgn (srcRgnA, srcRgnB, *destRgn);
- DisposeRgn (srcRgnA);
- DisposeRgn (srcRgnB);
- }
- else
- {
- result = memFullErr;
- }
- }
- else
- {
- result = nilHandleErr;
- }
- return (result);
- }
-
- /* ---------------------------------------------------------------------- */
-
- #pragma mark -
-
- // Create a GWorld that will hold our video - Just hardcode the size for now
-
- GWorldPtr MakeOffscreenGWorld (void)
- {
- GWorldPtr gwpOffscreen = NULL;
- Rect rBounds;
- QDErr qdeOffscreen = noErr;
-
- SetRect (&rBounds, 0, 0, 720, 480);
- qdeOffscreen = NewGWorld (&gwpOffscreen, 0, &rBounds, NULL, NULL, 0);
-
- if ((qdeOffscreen == noErr) && (gwpOffscreen != NULL)) {
- PixMapHandle pmhOffscreen = GetGWorldPixMap (gwpOffscreen);
-
- if (pmhOffscreen != NULL) {
- GWorldPtr oldWorld;
- GDHandle oldDevice;
- RGBColor rgbWhite = { 65535, 65535, 65535 };
- RGBColor rgbBlack = { 0, 0, 0 };
-
- LockPixels (pmhOffscreen);
-
- GetGWorld (&oldWorld, &oldDevice);
- SetGWorld (gwpOffscreen, NULL);
-
- RGBForeColor (&rgbBlack);
- RGBBackColor (&rgbWhite);
- ClipRect (&rBounds);
- EraseRect (&rBounds);
-
- SetGWorld (oldWorld, oldDevice);
- }
- } else {
- gwpOffscreen = NULL;
- }
-
- MakeEffectDescription ();
- gSampleDescription = MakeSampleDescription (kWhichEffect, 720, 480);
- PrepareDecompressionSequence ();
-
- return gwpOffscreen;
- }
-
-
-
- void MakeEffectDescription (void)
- {
- // QTAtomContainer myEffectDesc = nil;
- OSType myType;
- OSErr myErr = noErr;
- long myLong;
-
- // Create a new, empty effect description
- myErr = QTNewAtomContainer(&gEffectDesc);
-
- // This example is an effect description for an SMPTE effect
- myType = kWhichEffect; //'MoSc';//kEmbossImageFilterType;
- myErr = QTInsertChild(gEffectDesc,
- kParentAtomIsContainer,
- kParameterWhatName,
- kParameterWhatID,
- 0,
- sizeof(myType),
- &myType,
- nil);
-
- // Now reference the two sources to be used. These will not be items
- // in an input map. Instead the source names used will be resolved in
- // the decompression sequence.
- myType = 'srcA';
- myErr = QTInsertChild(gEffectDesc,
- kParentAtomIsContainer,
- kEffectSourceName,
- 1,
- 0,
- sizeof(myType),
- &myType,
- nil);
-
-
- myErr = QTInsertChild(gEffectDesc,
- kParentAtomIsContainer,
- 'ColR',//'MsSz', //'ksiz',
- 1,
- 0,
- sizeof(gColorToReplace),
- &gColorToReplace,
- nil);
-
- /* myErr = QTInsertChild(gEffectDesc,
- kParentAtomIsContainer,
- 'CoRp',//'MsSz', //'ksiz',
- 2,
- 0,
- sizeof(gColorToReplaceWith),
- &gColorToReplaceWith,
- nil);*/
- // This example uses SMTPE effect number 74, so add a WipeID
- // parameter with the value 74
- myLong = 10; //10;//3;
- myErr = QTInsertChild(gEffectDesc,
- kParentAtomIsContainer,
- 'Smlr',//'MsSz', //'ksiz',
- 2,
- 0,
- sizeof(myLong),
- &myLong,
- nil);
-
- if (gParental) {
- myLong = 0;
- } else {
- myLong = 1; //10;//3;
- }
- myErr = QTInsertChild(gEffectDesc,
- kParentAtomIsContainer,
- 'blur',//'MsSz', //'ksiz',
- 3,
- 0,
- sizeof(myLong),
- &myLong,
- nil);
- }
-
-
- ImageDescriptionHandle MakeSampleDescription (OSType theEffectType, short theWidth,
- short theHeight)
- {
- ImageDescriptionHandle mySampleDesc = nil;
- OSErr myErr = noErr;
-
- // create a new sample description
- myErr = MakeImageDescriptionForEffect(theEffectType, &mySampleDesc);
- if (myErr != noErr)
- return(nil);
-
- // fill in the fields of the sample description
- (**mySampleDesc).width = theWidth;
- (**mySampleDesc).height = theHeight;
-
- return(mySampleDesc);
- }
-
-
- void PrepareDecompressionSequence (void)
- {
- HLock((Handle) gEffectDesc);
-
- DecompressSequenceBeginS(&gEffectSequenceID,
- gSampleDescription,
- StripAddress(*gEffectDesc),
- GetHandleSize(gEffectDesc),
- (CGrafPtr) gMonitor,
- nil,
- nil,
- nil,
- ditherCopy,
- nil,
- 0,
- codecNormalQuality,
- nil);
-
- HUnlock((Handle) gEffectDesc);
- }
-
-
-
- void CopyFrameToWindow (WindowPtr inWindow)
- {
- if (gTempFrame != NULL) {
- GrafPtr oldPort = NULL;
- Rect rWindowBounds;
- Rect srcRect;
- PixMapHandle pmhTempFrame = GetGWorldPixMap (gTempFrame);
- long frameRate;
- Str255 secString;
-
- gNumFrames++;
- if (gStartSeconds == 0) {
- GetDateTime (&gStartSeconds);
- } else {
- GetDateTime (&gSeconds);
- }
-
- rWindowBounds = inWindow->portRect;
- srcRect = rWindowBounds;
- OffsetRect (&srcRect, -srcRect.left, -srcRect.top);
-
- GetPort (&oldPort);
- SetPort (inWindow);
-
- // CopyBits ((BitMap*)(*pmhTempFrame), &(inWindow->portBits), &srcRect, &rWindowBounds, srcCopy, NULL);
- RunEffect (1,1);
-
- frameRate = gNumFrames / (gSeconds - gStartSeconds);
- MoveTo (50, 50);
- NumToString (frameRate, secString);
- DrawString (secString);
-
- SetPort (oldPort);
- }
- }
-
-
- void LinkUpSources (void)
- {
- OSErr myErr = noErr;
- ImageSequenceDataSource mySrc1 = 0;
- PixMapHandle pmhTempFrame = GetGWorldPixMap (gTempFrame);
-
- // Generate a description of the first graphics world and store it in
- // gWorld1Desc
- myErr = MakeImageDescriptionForPixMap(pmhTempFrame, //gWorld1->portPixMap,
- &gSampleDescription);
-
- // Create a source from the graphics world description.
- myErr = CDSequenceNewDataSource(gEffectSequenceID,
- &mySrc1,
- 'srcA',
- 1,
- (Handle)gSampleDescription,
- nil,
- 0);
-
- // Set the data for source srcA to be the pixMap of the graphics
- // world gWorld1
- CDSequenceSetSourceData(mySrc1, GetPixBaseAddr(pmhTempFrame), (**gSampleDescription).dataSize);
-
- SetTimeBaseRate(gTimeBase, 0);
- CDSequenceSetTimeBase(gEffectSequenceID, gTimeBase);
- }
-
- // Decompress a single step of the effect sequence at time.
- OSErr RunEffect(TimeValue theTime, int theNumberOfSteps)
- {
- OSErr err = noErr;
- ICMFrameTimeRecord frameTime;
-
- // Set the timebase time to the step of the sequence to be rendered
- SetTimeBaseValue(gTimeBase, theTime, theNumberOfSteps);
-
- frameTime.value.lo = theTime;
- frameTime.value.hi = 0;
- frameTime.scale = theNumberOfSteps;
- frameTime.base = 0;
- frameTime.duration = theNumberOfSteps;
- frameTime.rate = 0;
- frameTime.recordSize = sizeof(frameTime);
- frameTime.frameNumber = 1;
- frameTime.flags = icmFrameTimeHasVirtualStartTimeAndDuration;
- frameTime.virtualStartTime.lo = 0;
- frameTime.virtualStartTime.hi = 0;
- frameTime.virtualDuration = theNumberOfSteps;
-
- HLock(gEffectDesc);
- DecompressSequenceFrameWhen(gEffectSequenceID,
- StripAddress(*gEffectDesc),
- GetHandleSize(gEffectDesc),
- 0,
- 0,
- nil,
- &frameTime);
- HUnlock(gEffectDesc);
- }
-
-
-
- void GetSkinTone (RGBColor* prgbColor)
- {
- NColorPickerInfo pickInfo;
-
- SGPause (gSeqGrabber, 1);
-
- BlockZero (&pickInfo, sizeof (pickInfo));
-
- pickInfo.theColor.color.rgb.red = 40000;
- pickInfo.theColor.color.rgb.green = 25000;
- pickInfo.theColor.color.rgb.blue = 15000;
- pickInfo.dstProfile = NULL;
- pickInfo.flags = kColorPickerDialogIsMoveable | kColorPickerDialogIsModal;
- pickInfo.placeWhere = kCenterOnMainScreen;
- pickInfo.dialogOrigin.h = 0;
- pickInfo.dialogOrigin.v = 0;
- pickInfo.pickerType = 0;
- pickInfo.eventProc = NULL;
- pickInfo.colorProc = NULL;
- pickInfo.colorProcData = 0;
- pickInfo.prompt [ 0 ] = 0;
- pickInfo.reserved = 0;
-
- NPickColor (&pickInfo);
-
- prgbColor->red = pickInfo.theColor.color.rgb.red;
- prgbColor->green = pickInfo.theColor.color.rgb.green;
- prgbColor->blue = pickInfo.theColor.color.rgb.blue;
-
- MakeEffectDescription ();
- gSampleDescription = MakeSampleDescription (kWhichEffect, 720, 480);
- PrepareDecompressionSequence ();
- LinkUpSources ();
-
- SGPause (gSeqGrabber, 0);
-
- GetDateTime (&gStartSeconds);
- gNumFrames = 0;
- }
-
-
-
- void ToggleParentalFilter (void)
- {
- SGPause (gSeqGrabber, 1);
-
- gParental = !gParental;
-
- MakeEffectDescription ();
- gSampleDescription = MakeSampleDescription (kWhichEffect, 720, 480);
- PrepareDecompressionSequence ();
- LinkUpSources ();
-
- SGPause (gSeqGrabber, 0);
-
- GetDateTime (&gStartSeconds);
- gNumFrames = 0;
- }
-